﻿using System;
using System. Linq;
using System. Net;
using System. Windows;
using System. Windows. Controls;
using System. Windows. Data;
using System. Xml. Linq;
using Microsoft. Phone. Controls;
using Microsoft. Phone. Shell;
using NextApp. WP7. AppConfig;
using NextApp. WP7. Models;
using WP7_ControlsLib. Controls;
using System. Collections. ObjectModel;
using NextApp. WP7. Cache. NextApp;
using System. Windows. Media;

namespace NextApp. WP7. View. Controls
{
    public partial class CommentList : UserControl
    {
        #region Initialize
        public CommentList( )
        {
            InitializeComponent( );
            this. Loaded += new RoutedEventHandler(CommentList_Loaded);
			this. commentsBinding. Add(this. loadNextTip);
			this. list_Comments. ItemsSource = this. commentsBinding;
			this. loadNextTip. Click += (s, e) =>
				{
					this. LoadNextComments( );
				};
			//滚动检测
			this. list_Comments. LayoutUpdated += new EventHandler(list_Comments_LayoutUpdated);
			if ( this.IsHostByMainPage == false)
			{
				this. list_Comments. ItemTemplate = this. Resources[ "template_1" ] as DataTemplate;
				this. loadNextTip. Foreground = new SolidColorBrush(Colors. Black);
			}
        }
		private LoadNextTip loadNextTip = new LoadNextTip
		{
			Text = "正在刷新",
			HorizontalAlignment = HorizontalAlignment. Center,
			HorizontalContentAlignment = HorizontalAlignment. Center,
			FontSize = 34,
			Width = 480,
			MinWidth = 480,
			Height = 100,
			MinHeight = 100,
		};
		public void GetTemplate( bool isHostByMainPage )
		{
			if ( this.list_Comments != null )
			{
				this. list_Comments. ItemTemplate = isHostByMainPage ? this. Resources[ "template_2" ] as DataTemplate : this. Resources[ "template_1" ] as DataTemplate;
			}
		}

        private const int fetchCount = 10;
        private int fromComment;
        public int postID { get; set; }
		public bool IsHostByMainPage { get; set; }
        public bool IsLoadingData { get; set; }
		private ObservableCollection<object> commentsBinding = new ObservableCollection<object>( );
		private ScrollViewer listBox_ScrollViewer;
		private double lastListBoxScrollableVerticalOffset = 0;
       #endregion

		#region 获取/刷新 数据
		void list_Comments_LayoutUpdated(object sender, EventArgs e)
		{
			if ( this. listBox_ScrollViewer != null )
			{
				//是否往下滑动
				bool isGoingDown = this. listBox_ScrollViewer. VerticalOffset > lastListBoxScrollableVerticalOffset;
				this. lastListBoxScrollableVerticalOffset = this. listBox_ScrollViewer. VerticalOffset;
				//是否在监控的最底部区域
				bool isInReloadRegion = this. listBox_ScrollViewer. VerticalOffset >= ( this. listBox_ScrollViewer. ScrollableHeight - Config. ScrollBarOffset );
				//当两者都满足时  开始刷新数据
				if ( isInReloadRegion &&
					isGoingDown )
				{
					this. LoadNextComments( );
				}
			}
			else
			{
				this. listBox_ScrollViewer = ControlHelper. FindChildOfType<ScrollViewer>(this. list_Comments);
			}
		}
		private void LoadNextComments( )
		{
			if ( this. IsLoadingData )
			{
				System. Diagnostics. Debug. WriteLine("评论刷新中 无法重新获取");
				return;
			}
			if ( this. commentsBinding. IsNotNullOrEmpty( ) && this. commentsBinding. Count >= 2 )
			{
				Comment lastComment = this. commentsBinding[ this. commentsBinding. Count - 2 ] as Comment;
				if ( lastComment != null )
				{
					this. fromComment = lastComment. id;
					this. Reload(false);
				}
			}
		}
        public void Reload( bool isInitialize = true, int postID = 0, int from = -1, bool isClearItemSource = false )
        {
			//是否需要清空缓存
			if ( isClearItemSource )
            {
				this. commentsBinding. Clear( );
				this. commentsBinding. Add(this. loadNextTip);
				this. loadNextTip. Text = "正在刷新";
            }
			string url = Config. Instance. GetApi(string. Format("{0}&post={1}&fromComment={2}&fetchCount={3}&guid={4}",
																					NextAppSingleton. Instance. url_comment_list,
																					IsHostByMainPage ? 0 : this.postID,
																					from < 0 ? fromComment : from,
																					fetchCount,
																					Guid. NewGuid( )));
            //检查缓存
			if ( this. CheckIsCached(from ) )
			{
				//入队操作
				CacheNextApp. Instance. Enqueue(new AsyncMissionNextApp
				{
					 Type = AsyncMissionNextAppType.Comment_List,
					queryStringWithUrl = url,
				});
			}
			else
			{
				WebClient client = new WebClient( );
				client. Headers[ "User-Agent" ] = Config. Instance. Http_User_Agent;
				client. DownloadStringCompleted += (s, e1) =>
				{
					#region 对返回的结果进行分析
					if ( e1. Error != null )
					{
						MessageBox. Show("获取评论列表失败", "网络错误", MessageBoxButton. OK);
						return;
					}
					XElement x;
					try
					{
						x = XElement. Parse(e1. Result);
					}
					catch ( Exception )
					{
						return;
					}
					CommentsList comments = new CommentsList
					{
						commentCount = x. Element("commentCount"). Value. ToInt32( ),
						comments = x. Element("comments") == null ?
											null :
											x. Element("comments"). Elements("comment"). Select(
															c => new Comment
															{
																id = c. Element("id"). Value. ToInt32( ),
																post = c. Element("post"). Value. ToInt32( ),
																name = c. Element("name"). Value,
																email = c. Element("email"). Value,
																url = c. Element("url"). Value,
																body = c. Element("body"). Value,
																pubDate = c. Element("pubDate"). Value,
															}). ToArray( ),
					};
					#endregion

					#region 如果此次获取到了一些消息
					if ( comments. comments != null )
					{
						this. loadNextTip. Text = "更多 . . .";
						//存储到缓存
						CacheNextApp. Instance. SaveCommentsToCache(comments. comments);

						//首先获取评论列表的ID集合
						int[ ] commentsIDS = this. GetCurrentCommentsIDS;
						//然后插入数据 这里需要判断重复性
						comments. comments = comments. comments. Where(c => commentsIDS. Contains(c. id) == false). ToArray( );
						comments. comments. ForAll(c => this. commentsBinding. Insert(this. commentsBinding. Count - 1, c));
						if ( comments.comments.Length > 0 )
						{
							//入队 预估计判断
							CacheNextApp. Instance. Enqueue(new AsyncMissionNextApp
							{
								 Type = AsyncMissionNextAppType.Comment_List,
								queryStringWithUrl = Config. Instance. GetApi(string. Format("{0}&post={1}&fromComment={2}&fetchCount={3}&guid={4}",
																												  NextAppSingleton. Instance. url_comment_list,
																												  IsHostByMainPage ? 0 : this. postID,
																												  comments. comments. LastOrDefault( ). id,
																												  fetchCount,
																												  Guid. NewGuid( ))),
							});
						}
						//不显示 无评论提示
						this. tblock_NoCommentsTip. Visibility = System. Windows. Visibility. Collapsed;
					}
					#endregion

					#region 如果此次获取没有任何消息返回 则显示没有评论的提示
					else
					{
						if ( isInitialize && this. list_Comments. Items. Count <= 0 )
						{
							this. tblock_NoCommentsTip. Text = "没有评论";
							this. tblock_NoCommentsTip. Visibility = System. Windows. Visibility. Visible;
						}
						else
						{
							this. loadNextTip. Text = "已经没有最新评论";
						}
					}
					#endregion

					//隐藏进度条
					this. IsDisplayProgressBar(false);
				};

				#region 异步获取数据
				if ( NextAppSingleton. Instance. url_comment_list. IsNotNullOrWhitespace( ) )
				{
					client. DownloadStringAsync(new Uri(url, UriKind. Absolute));
					//显示进度条
					this. IsDisplayProgressBar(true);
				}
			}
			#endregion
		}
        //检查缓存
        private bool CheckIsCached( int from )
        {
			Comment[ ] comments = CacheNextApp. Instance. GetCommentListFromCache(postID, from < 0 ? fromComment : from, fetchCount, IsHostByMainPage);
			if ( comments != null && comments.Length > 0 )
			{
				//首先获取评论列表的ID集合
				int[ ] commentsIDS = this. GetCurrentCommentsIDS;
				//然后插入数据 这里需要判断重复性
				comments = comments. Where(c => commentsIDS. Contains(c. id) == false). ToArray( );
				if ( comments. Length <= 0 && fromComment > 0)
				{
					return false;
				}
				comments. ForAll(c => this. commentsBinding. Insert(this. commentsBinding. Count - 1, c));
				this. loadNextTip. Text = "更多 . . .";
				return true;
			}
			else
			{
				return false;
			}
        }
		private int[ ] GetCurrentCommentsIDS
		{
			get
			{
				int[ ] commentsIDS = this. commentsBinding. Select(c =>
				{
					Comment tempC = c as Comment;
					return tempC == null ? -1 : tempC. id;
				}). ToArray( );
				return commentsIDS;
			}
		}
		#endregion

		#region 删除评论
		private void menuItem_DeleteComment_Click(object sender, RoutedEventArgs e)
		{
			if ( Config. Instance. Cookie. IsNullOrWhitespace( ) )
			{
				if ( MessageBox. Show("您还没有登陆, 请登陆", "无法删除", MessageBoxButton. OKCancel) == MessageBoxResult. OK )
				{
					Util. Tool. Login( );
				}
				return;
			}
			MenuItem menuItem = sender as MenuItem;
			if ( menuItem != null )
			{
				int commentID = menuItem. Tag. ToString( ). ToInt32( );
				if ( MessageBox. Show("您确认删除这个评论吗?", "确认删除吗", MessageBoxButton. OKCancel) == MessageBoxResult. OK )
				{
					this. DeleteCommentByID(commentID);
				}
			}
		}
        private void DeleteCommentByID(int id)
        {
			WebClient client = new WebClient( );
			client. Headers[ "User-Agent" ] = Config. Instance. Http_User_Agent;

			#region 异步的返回结果操作
			client. DownloadStringCompleted += (s, e1) =>
            {
                if ( e1. Error != null )
                {
                    System. Diagnostics. Debug. WriteLine("删除评论失败: {0}", e1. Error. Message);
                    return;
                }
				XElement osmobile;
				try
				{
					osmobile = XElement. Parse(e1. Result);
				}
				catch ( Exception )
				{
					return;
				}
                ApiError _error = new ApiError
                {
                    errorCode = osmobile. Element("result"). Element("errorCode"). Value. ToInt32( ),
                    errorMessage = osmobile. Element("result"). Element("errorMessage"). Value,
                };
			

				//隐藏进度条
                this. IsDisplayProgressBar(false);
                //显示删除结果 如果删除成功 则清空该类型评论的缓存以及通知刷新评论
                if ( this.DisplayResult_DeleteComment(_error) )
                {
					this. commentsBinding. Remove(this. commentsBinding. FirstOrDefault(c =>
						{
							Comment _c = c as Comment;
							if ( _c != null )
								return _c. id == id;
							else
								return false;
						}));
                }
            };
			#endregion

			#region 异步操作开始
			if ( NextAppSingleton.Instance.url_comment_delete.IsNotNullOrWhitespace() )
            {
				client. Headers[ "Cookie" ] = Config. Instance. Cookie;
                client. DownloadStringAsync(new Uri(Config. Instance. GetApi(string. Format("{0}&comment={1}", NextAppSingleton. Instance. url_comment_delete, id)),
                                                                UriKind. Absolute));
                //显示进度条
                this. IsDisplayProgressBar(true);
			}
			#endregion
		}
        private bool DisplayResult_DeleteComment( ApiError error )
        {
            switch ( error.errorCode )
            {
                case 1:
                    MessageBox. Show("评论删除成功");
                    return true;
                case 0:
                    MessageBox. Show("对不起, 用户未登录, 无法删除");
                    return false;
                case -1:
                    MessageBox. Show("对不起, 无法删除, 其他错误");
                    return false;
                case -2:
                    MessageBox. Show("对不起, 您没有删除评论的权限");
                    return false;
            }
            return false;
        }

        #endregion

        #region 点击评论后的处理  是否跳转到文章详情页
        public bool IsEnableClick { get; set; }
        private void list_Comments_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if ( this.IsEnableClick )
            {
                Comment c = this. list_Comments. SelectedItem as Comment;
                if ( c != null )
                {
                    ( Application. Current. RootVisual as PhoneApplicationFrame ). Navigate(new Uri(string. Format("/View/PostDetail.xaml?post={0}&portal=comments", c. post), UriKind. Relative));
                }
            }
            this. list_Comments. SelectedItem = null;
        }
        #endregion

        #region 进度条控制
		private void IsDisplayProgressBar(bool visible)
		{
			if ( this. IsHostByMainPage )
			{
				EventSingleton. Instance. RaiseOnMainPageLoading(visible);
			}
			else
			{
				this. ProgressIndicatorIsVisible = visible;
			}
			//加载指示器
			this. IsLoadingData = visible;
		}
        private void CommentList_Loaded(object sender, RoutedEventArgs e)
        {
            SystemTray. ProgressIndicator = new ProgressIndicator( );
            SystemTray. ProgressIndicator. Text = "加载中";

            Binding bindingData;
            bindingData = new Binding("ProgressIndicatorIsVisible");
            bindingData. Source = this;
            BindingOperations. SetBinding(SystemTray. ProgressIndicator, ProgressIndicator. IsVisibleProperty, bindingData);
            BindingOperations. SetBinding(SystemTray. ProgressIndicator, ProgressIndicator. IsIndeterminateProperty, bindingData);
        }
        public static readonly DependencyProperty ProgressIndicatorIsVisibleProperty =
            DependencyProperty. Register("ProgressIndicatorIsVisible",
            typeof(bool),
            typeof(CommentList),
            new PropertyMetadata(false));

        public bool ProgressIndicatorIsVisible
        {
            get { return ( bool )GetValue(ProgressIndicatorIsVisibleProperty); }
            set { SetValue(ProgressIndicatorIsVisibleProperty, value); }
        }
        #endregion
    }
}
